package oss_util

import (
	"bufio"
	"context"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"time"
	common_config "trpg-common/config"
	"trpg-common/logger"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/credentials"
	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/pkg/errors"
)

var client *s3.Client
var bucketName = common_config.GetString("store.bucketName")

// var cacheControl = "public, max-age=3600"

func init() {
	cfg := aws.Config{
		Region:       "us-west-2",
		Credentials:  credentials.NewStaticCredentialsProvider(common_config.GetString("store.accessId"), common_config.GetString("store.accessKey"), ""),
		BaseEndpoint: aws.String(common_config.GetString("store.endpoint")),
	}
	// Create an Amazon S3 service client
	client = s3.NewFromConfig(cfg)
}

func DownloadFile(key string, desPath string) {
	object, err := client.GetObject(context.TODO(), &s3.GetObjectInput{
		Bucket: aws.String(bucketName),
		Key:    aws.String(key),
	})
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in get object from oss"))
	}
	desFile, err := os.Open(desPath)
	if err != nil {
		if os.IsNotExist(err) {
			// 不存在，创建文件
			desFile, err = os.Create(desPath)
			if err != nil {
				logger.Logger.Panicf("%+v", errors.Wrap(err, "error in create file"))
			}
		} else {
			logger.Logger.Panicf("%+v", errors.Wrap(err, "error in open desPath"))
		}
	}
	defer object.Body.Close()
	defer desFile.Close()
	reader := bufio.NewReader(object.Body)
	writer := bufio.NewWriter(desFile)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			break
		}
		_, err = writer.WriteString(line)
		if err != nil {
			logger.Logger.Panicf("%+v", errors.Wrap(err, "error in write to file"))
		}
	}
	err = writer.Flush()
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in flush buffer"))
	}
}

func DeleteFile(key string) {
	_, err := client.DeleteObject(context.TODO(), &s3.DeleteObjectInput{
		Bucket: aws.String(bucketName),
		Key:    aws.String(key),
	})
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in delete object on oss"))
	}
}

func UploadFileSetHeader(file io.Reader, desPath string, contentType string) string {
	metadata := map[string]string{"ContentUrl-Disposition": "inline"}
	if contentType != "" {
		metadata["ContentUrl-Type"] = contentType + "; charset=utf-8"
	}
	_, err := client.PutObject(context.TODO(), &s3.PutObjectInput{
		Bucket:   aws.String(bucketName),
		Key:      aws.String(desPath),
		Body:     file,
		Metadata: metadata,
	})
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in upload file"))
	}
	preSignClient := s3.NewPresignClient(client)
	res, err := preSignClient.PresignGetObject(context.TODO(), &s3.GetObjectInput{
		Bucket: aws.String(bucketName),
		Key:    aws.String(desPath),
	}, func(options *s3.PresignOptions) {
		options.Expires = 5 * 24 * time.Hour // 设置 URL 过期时间
	})
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in upload file"))
	}
	return res.URL
}

func UploadFile(srcPath string, desPath string) string {
	file, err := os.Open(srcPath)
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in open file"))
	}
	return UploadFileSetHeader(file, desPath, "")
}

func UploadMultiFile(file *multipart.FileHeader, desPath string) string {
	open, err := file.Open()
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in open file"))
	}
	return UploadFileSetHeader(open, desPath, "")
}

func GetStreamFromUrl(url string) io.ReadCloser {
	resp, err := http.Get(url)
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in get file from url"))
	}
	if resp.StatusCode != 200 {
		logger.Logger.Panicf("%+v", errors.Wrap(errors.New("error status code: "+string(rune(resp.StatusCode))), "error in get file from url"))
	}
	return resp.Body
}

func GetUrlByKey(key string) string {
	// preSignClient := s3.NewPresignClient(client)
	// res, err := preSignClient.PresignGetObject(context.TODO(), &s3.GetObjectInput{
	// 	Bucket:               aws.String(bucketName),
	// 	Key:                  aws.String(key),
	// 	ResponseCacheControl: &cacheControl,
	// }, func(options *s3.PresignOptions) {
	// 	options.Expires = 5 * 24 * time.Hour // 设置 URL 过期时间
	// })
	// if err != nil {
	// 	logger.Logger.Panicf("%+v", errors.Wrap(err, "error in get file url"))
	// }
	// return res.URL
	return "http://119.45.201.47:9000/trpg" + key
}

func GetUniqueUrlByKey(key string) string {
	preSignClient := s3.NewPresignClient(client)
	res, err := preSignClient.PresignGetObject(context.TODO(), &s3.GetObjectInput{
		Bucket: aws.String(bucketName),
		Key:    aws.String(key),
	}, func(options *s3.PresignOptions) {
		options.Expires = 5 * 24 * time.Hour // 设置 URL 过期时间
	})
	if err != nil {
		logger.Logger.Panicf("%+v", errors.Wrap(err, "error in get file url"))
	}
	return res.URL
}
